package xcmg.device.service.delivery;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.PriMaterialsDO;
import xcmg.device.dao.entity.delivery.DeliveryReceiptDO;
import xcmg.device.dao.entity.delivery.DeliveryReceiptMaterialDO;
import xcmg.device.dao.entity.warehouse.WarehouseDeliveryDetailDO;
import xcmg.device.dao.mapper.PriMaterialsMapper;
import xcmg.device.dao.mapper.delivery.DeliveryReceiptLinkMapper;
import xcmg.device.dao.mapper.delivery.DeliveryReceiptMaterialMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryDetailMapper;
import xcmg.device.infra.ErrorCode;
import xcmg.device.service.vo.delivery.DeliveryReceiptMaterialVO;
import xcmg.device.service.warehouse.WarehouseDeliveryService;
import yb.ecp.fast.feign.AuthClient;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.log.LogHelper;
import yb.ecp.fast.infra.util.ListUtil;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
public class DeliveryReceiptMaterialService {


    @Autowired
    private DeliveryReceiptMaterialMapper deliveryReceiptMaterialMapper;

    @Autowired
    private FastGenClient fastGenClient;

    @Autowired
    private WarehouseDeliveryService warehouseDeliveryService;

    @Autowired
    private PriMaterialsMapper priMaterialsMapper;

    @Autowired
    private WarehouseDeliveryDetailMapper warehouseDeliveryDetailMapper;

    @Autowired
    private AuthClient authClient;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private DeliveryReceiptLinkMapper deliveryReceiptLinkMapper;

    public void add(List<String> outIds, DeliveryReceiptDO deliveryReceiptDO) throws Exception {
        String orgId = deliveryReceiptDO.getOrgId();
        List<DeliveryReceiptMaterialDO> materialDOList;
        switch (deliveryReceiptDO.getBillType()) {
            case "XGFT":
                materialDOList = deliveryReceiptMaterialMapper.listByDeliveryNote(orgId ,outIds);
                break;
            case "XGSC":
                materialDOList = deliveryReceiptMaterialMapper.listByThreeOut(outIds);
                break;
            case "XGQD":
                materialDOList = deliveryReceiptMaterialMapper.listByRegionOut(outIds);
                break;
            case "XGFC":
                materialDOList = deliveryReceiptMaterialMapper.listByAbnoarmalOut(outIds);
                break;
            case "XSCK":
                materialDOList = deliveryReceiptMaterialMapper.listBySalesOutBill(outIds);
                break;
            default:
                materialDOList = null;
        }
        if (ListUtil.isNullOrEmpty(materialDOList)) {
            throw new Exception("未找到零件详情");
        }
        for (DeliveryReceiptMaterialDO materialDO : materialDOList) {
            materialDO.setId(fastGenClient.textGuid().getValue());
            materialDO.setDeliveryReceiptId(deliveryReceiptDO.getId());
            materialDO.setDeliveryReceiptNo(deliveryReceiptDO.getBillNo());
            deliveryReceiptMaterialMapper.insert(materialDO);
        }

        warehouseDeliveryService.saveByDeliveryReceipt(deliveryReceiptDO.getBillNo(), materialDOList, deliveryReceiptDO.getCreateId(), deliveryReceiptDO.getOrgId());
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean updateByOut(DeliveryReceiptMaterialDO materialDO, BigDecimal outQty) throws Exception {
        materialDO.setOutQty(outQty);
        if (outQty.compareTo(materialDO.getQty()) == 0) {
            materialDO.setOutStatus(2);
        } else {
            materialDO.setOutStatus(1);
        }
        boolean success = deliveryReceiptMaterialMapper.update(materialDO) > 0;
        if (!success) {
            throw new Exception("更新发运交接单出库状态失败");
        }
        Integer status = deliveryReceiptMaterialMapper.findOutStatus(materialDO.getDeliveryReceiptId());
        success = deliveryReceiptMaterialMapper.updateMainOutStatus(materialDO.getDeliveryReceiptId(), status) > 0;
        if (!success) {
            throw new Exception("更新发运交接单出库状态失败");
        }

        success = deliveryReceiptMaterialMapper.updateBaseDetailStatus(materialDO.getDeliveryReceiptNo(), materialDO.getMaterialsNo(),
                materialDO.getOutQty(), materialDO.getOutStatus()) > 0;
        if (!success) {
            throw new Exception("更新发运交接单出库状态失败");
        }
        success = deliveryReceiptMaterialMapper.updateBaseOutStatus(materialDO.getDeliveryReceiptNo(), status) > 0;
        if (!success) {
            throw new Exception("更新发运交接单出库状态失败");
        }
        return true;
    }

    /**运单入库结单时更新发运交接单创建入库单状态和数量*/
    @Transactional(rollbackFor = Exception.class)
    public boolean manualUpdateSendStatus(String receiptNo, String materialNo, BigDecimal qty) throws Exception {
        DeliveryReceiptMaterialDO receiptMaterialDO = deliveryReceiptMaterialMapper.findByMaterialNo(receiptNo, materialNo);
        if (receiptMaterialDO == null) {
            throw new Exception("未找到发运交接单零件详情");
        }
        BigDecimal sendQty = receiptMaterialDO.getSendQty().add(qty);
        if (sendQty.compareTo(receiptMaterialDO.getQty()) > 0) {
            throw new Exception("运单入库结单数量不能大于原数量");
        }
        boolean success = deliveryReceiptMaterialMapper.updateSendQty(receiptNo, materialNo, sendQty) > 0;
        if (!success) {
            throw new Exception("更新已建入库数量失败");
        }
        Integer sendStatus = deliveryReceiptMaterialMapper.findSendStatus(receiptMaterialDO.getDeliveryReceiptId());
        success = deliveryReceiptMaterialMapper.updateMainSendStatus(receiptMaterialDO.getDeliveryReceiptId(), sendStatus) > 0;
        if (!success) {
            throw new Exception("更新已建入库状态失败");
        }
        return true;
    }


    @Transactional(rollbackFor = Exception.class)
    public boolean updateSendStatus(String receiptId, String receiptNo, String materialNo, BigDecimal qty) throws Exception {
        DeliveryReceiptMaterialDO receiptMaterialDO = deliveryReceiptMaterialMapper.findByMaterialNo(receiptNo, materialNo);
        if (receiptMaterialDO == null) {
            throw new Exception("未找到发运交接单零件详情");
        }
        BigDecimal sendQty = receiptMaterialDO.getSendQty().add(qty);
        if (sendQty.compareTo(receiptMaterialDO.getQty()) > 0) {
            throw new Exception("创建入库数量不能大于原数量");
        }
        boolean success = deliveryReceiptMaterialMapper.updateSendQty(receiptNo, materialNo, sendQty) > 0;
        if (!success) {
            throw new Exception("更新已建入库数量失败");
        }
        Integer sendStatus = deliveryReceiptMaterialMapper.findSendStatus(receiptId);
        success = deliveryReceiptMaterialMapper.updateMainSendStatus(receiptId, sendStatus) > 0;
        if (!success) {
            throw new Exception("更新已建入库状态失败");
        }
        return true;
    }


    public List<DeliveryReceiptMaterialVO> list(String receiptId, String orgId) {
        List<DeliveryReceiptMaterialDO> materialDOList = deliveryReceiptMaterialMapper.list(receiptId);
        List<DeliveryReceiptMaterialVO> materialVOList = new ArrayList<>();
        if (!ListUtil.isNullOrEmpty(materialDOList)) {
            PriMaterialsDO priMaterialsDO;
            for (DeliveryReceiptMaterialDO materialDO : materialDOList) {
                DeliveryReceiptMaterialVO materialVO = new DeliveryReceiptMaterialVO();
                BeanUtils.copyProperties(materialDO, materialVO);
                priMaterialsDO = priMaterialsMapper.itemByNo(materialDO.getMaterialsNo(), orgId);
                if (priMaterialsDO != null) {
                    materialVO.setMaterialsType(priMaterialsDO.getMaterialsType());
                }
                materialVOList.add(materialVO);
            }
        }
        return materialVOList;
    }

    public void updateByAdjust(List<String> ids, List<DeliveryReceiptMaterialVO> list) {
        if (ListUtil.isNullOrEmpty(ids) || ListUtil.isNullOrEmpty(list)) {
            return;
        }
        List<DeliveryReceiptMaterialDO> materialDOList = deliveryReceiptMaterialMapper.listByIds(ids, null);
        if (ListUtil.isNullOrEmpty(materialDOList)) {
            return;
        }

        for (DeliveryReceiptMaterialVO outter : list) {
            for (DeliveryReceiptMaterialDO inner : materialDOList) {
                if (inner.getMaterialsNo().equals(outter.getMaterialsNo()) && inner.getDeliveryReceiptId().equals(outter.getDeliveryReceiptId())) {
                    WarehouseDeliveryDetailDO deliveryDetailDO = warehouseDeliveryDetailMapper.itemByMaterialsNo(getOrgId(), inner.getDeliveryReceiptNo(), inner.getMaterialsNo());
                    if (outter.getUpdateType() == 0) {
                        //删除类型
                        if (inner.getQty().compareTo(outter.getQty()) == 0) {
                            deliveryReceiptMaterialMapper.deleteByPrimaryKey(inner.getId());

                            warehouseDeliveryDetailMapper.deleteByPrimaryKey(deliveryDetailDO.getId());
                        } else {
                            inner.setQty(inner.getQty().subtract(outter.getQty()));
                            deliveryReceiptMaterialMapper.update(inner);

                            deliveryDetailDO.setAmount(inner.getQty());
                            warehouseDeliveryDetailMapper.updateByPrimaryKey(deliveryDetailDO);
                        }
                    } else {
                        //更新类型
                        BigDecimal qty = inner.getQty().subtract(outter.getOldQty()).add(outter.getQty());
                        inner.setQty(qty);
                        deliveryReceiptMaterialMapper.update(inner);

                        deliveryDetailDO.setAmount(inner.getQty());
                        warehouseDeliveryDetailMapper.updateByPrimaryKey(deliveryDetailDO);
                    }
                    break;
                }
            }
        }
    }

    private String getOrgId(){
        String userId = request.getHeader("x-user-id");
        try {
            ActionResult actionResult = authClient.queryWorkspaceId(userId);
            return (String) actionResult.getValue();
        }catch (Exception e){
            LogHelper.error(e.getMessage(), ErrorCode.RequestIdError.getCode());
        }
        return "";
    }
}

